let ctx = null;
let canvas = null;
let points = [];
const CLOSE_polygon_distance = 10;
let originData = [];
export default {
  data() {
    return {
      polygonData: [],
    };
  },
  methods: {
    initPolygon() {
      canvas = document.getElementById("myCanvas");
      ctx = canvas.getContext("2d");
      this._drawType = "polygon";
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      canvas.addEventListener("click", this.polygon_onClick);
      canvas.addEventListener("mousemove", this.polygon_onMousemove);
    },
    getPolygons() {
      return this.polygonData.slice(0, this.polygonData.length - 1);
    },
    // 还原多边形
    cancelPolygon() {
      if (!ctx) return;
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      this.polygon_removeEvent()
      this.polygonData = [...originData];
      points=[]
      this.polygon_draw();
      this.line_draw();
    },
    polygon_onMousemove(e) {
      if (points.length === 0) return;
      const {
        x,
        y
      } = this.polygon_getMousepos(e);
      this.drawPointsAndLines();
      const lastPoint = points[points.length - 1];
      this.drawAnimationLine(x, y, lastPoint);
      this.drawFirstPoint({
        x,
        y
      });
    },
    // 鼠标move时绘制最后一根移动的线
    drawAnimationLine(x, y, lastPoint) {
      // 需要判断有没有交叉
      ctx.save()
      ctx.strokeStyle = "#f00";
      ctx.beginPath();
      ctx.moveTo(lastPoint.x, lastPoint.y);
      ctx.lineTo(x, y);
      ctx.stroke();
      ctx.restore();
    },
    drawFirstPoint(lastPoint) {
      // 这里判断如果鼠标位置与第一个点重合,则放大第一个点
      const firstPoint = points[0];
      if (
        this.polygon_distance(firstPoint, lastPoint) < CLOSE_polygon_distance &&
        points.length > 2
      ) {
        ctx.strokeStyle="#ccc";
        ctx.beginPath();
        ctx.arc(firstPoint.x, firstPoint.y, 10, 0, 2 * Math.PI);
        ctx.stroke();
      }
    },
    polygon_onClick(e) {
      const lastPoint  = this.polygon_getMousepos(e);
      if (points.length > 0) {
        const firstPoint = points[0];
        // 如果画的点与第一个点重合,则结束绘制,闭合
        if (
          this.polygon_distance(firstPoint, lastPoint) <
          CLOSE_polygon_distance &&
          points.length > 2
        ) {
          points.push(firstPoint);
          this.drawPolygon();
          this.polygonData = [...points];
          points.length = 0; // Reset points array
          this.polygon_drawEnd && this.polygon_drawEnd();
          this.polygon_removeEvent();
          // 如果已经绘制了长方形,则一起绘制出来
          this.rect_draw && this.rect_draw();
          this.line_draw && this.line_draw();
          return;
        }
      }
      let len = points.length;
      // 这里判断如果想要画的新的一根线和之前的线段有交叉,则不画
      if(this.isIntersectWithPoints(points[len-1],lastPoint)) {
        return;
      }
      points.push(lastPoint);
      this.drawPointsAndLines();
    },
    polygon_removeEvent() {
      canvas.removeEventListener("click", this.polygon_onClick);
      canvas.removeEventListener("mousemove", this.polygon_onMousemove);
    },
    polygon_distance(p1, p2) {
      return Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2);
    },
    drawPolygon() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.save();
      ctx.strokeStyle = "#ccc";
      ctx.beginPath();
      for (let i = 0; i < points.length; i++) {
        if (i === 0) {
          ctx.moveTo(points[i].x, points[i].y);
        } else {
          ctx.lineTo(points[i].x, points[i].y);
        }
        // ctx.arc(points[i].x, points[i].y, 3, 0, Math.PI * 2, true);
        // ctx.moveTo(points[i].x, points[i].y);
      }
      ctx.closePath();
      ctx.stroke();
      ctx.restore();
    },
    /**
     * 
     * @param {是否是打开弹窗回显过来的,true则代表是打开弹窗,需要保存原始数据} flag 
     * @returns 
     */
    polygon_draw(flag) {
      if (!this.polygonData || this.polygonData.length === 0) return;
      canvas = document.getElementById("myCanvas");
      ctx = canvas.getContext("2d");
      const {
        polygonData
      } = this;
      flag && (originData = [...polygonData]);
      polygonData.push(polygonData[0]);
      ctx.save();
      ctx.strokeStyle = "#ccc";
      ctx.beginPath();
      for (let i = 0; i < polygonData.length; i++) {
        if (i === 0) {
          ctx.moveTo(polygonData[i].x, polygonData[i].y);
        } else {
          ctx.lineTo(polygonData[i].x, polygonData[i].y);
        }
        // ctx.arc(polygonData[i].x, polygonData[i].y, 3, 0, Math.PI * 2, true);
        // ctx.moveTo(polygonData[i].x, polygonData[i].y);
      }
      ctx.closePath();
      ctx.stroke();
      ctx.restore();
    },
    drawPointsAndLines() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.strokeStyle = "#ccc";
      ctx.beginPath();
      let len = points.length;
      for (let i = 0; i < len; i++) {
     
        if (i === 0) {
          ctx.moveTo(points[i].x, points[i].y);
        } else {
          ctx.lineTo(points[i].x, points[i].y);
        }
        // ctx.arc(points[i].x, points[i].y, 3, 0, Math.PI * 2, true);
        // ctx.moveTo(points[i].x, points[i].y);
      }
      ctx.stroke();
    },
    polygon_getMousepos(evt) {
      const rect = canvas.getBoundingClientRect();
      return {
        x: evt.clientX - rect.left,
        y: evt.clientY - rect.top,
      };
    },
    /**
     * 
     * @param {已经保存的最后一个点} point 
     * @param {当前绘制的点} lastPoint 
     * @returns 
     */
    isIntersectWithPoints(point, lastPoint) {
      let flag = false;
      if (points.length < 3) return flag;
      points.reduce((pre, cur) => {
        if (this.isIntersecting(pre, cur, point, lastPoint)) {
          flag = true;
        }
        return cur;
      })
      return flag;
    },
    crossProduct(P, Q, R) {
      return (Q.x - P.x) * (R.y - P.y) - (Q.y - P.y) * (R.x - P.x);
    },
    // 判断点 Q 是否在线段 PR 上（假设点是共线的）
    isPointOnSegment(P, Q, R) {
      return (
        Math.min(P.x, R.x) <= Q.x &&
        Q.x <= Math.max(P.x, R.x) &&
        Math.min(P.y, R.y) <= Q.y &&
        Q.y <= Math.max(P.y, R.y)
      );
    },
    // 判断两条线段是否相交
    isIntersecting(A, B, C, D) {
      const {
        crossProduct,
        isPointOnSegment
      } = this;
      const d1 = crossProduct(A, B, C);
      const d2 = crossProduct(A, B, D);
      const d3 = crossProduct(C, D, A);
      const d4 = crossProduct(C, D, B);
      if (d1 * d2 < 0 && d3 * d4 < 0) {
        return true; // 线段真正相交
      }
      // 检查共线且重合的情况
      // if (d1 === 0 && isPointOnSegment(A, C, B)) return true; // 这里注释掉因为C是已经绘制的最后一个点,不需要判断是否和其他线段重合,否则必然和最后一根线重合
      if (d2 === 0 && isPointOnSegment(A, D, B)) return true;
      if (d3 === 0 && isPointOnSegment(C, A, D)) return true;
      // if (d4 === 0 && isPointOnSegment(C, B, D)) return true;
      return false; // 线段不相交
    }
  }
};